struct netfront_info *np = dev->dev.driver_data;
struct net_device *netdev = np->netdev;
- DPRINTK("\n");
+ DPRINTK("%s\n", xenbus_strstate(backend_state));
switch (backend_state) {
case XenbusStateInitialising:
{
struct netfront_info *info = dev->dev.driver_data;
- DPRINTK("netfront_closing: %s removed\n", dev->nodename);
+ DPRINTK("%s\n", dev->nodename);
close_netdev(info);
-
- xenbus_switch_state(dev, XenbusStateClosed);
+ xenbus_frontend_closed(dev);
}
static int xenbus_dev_probe(struct device *_dev);
static int xenbus_dev_remove(struct device *_dev);
+static void xenbus_dev_shutdown(struct device *_dev);
/* If something in array of ids matches this device, return it. */
static const struct xenbus_device_id *
.match = xenbus_match,
.probe = xenbus_dev_probe,
.remove = xenbus_dev_remove,
+ .shutdown = xenbus_dev_shutdown,
},
.dev = {
.bus_id = "xen",
.match = xenbus_match,
.probe = xenbus_dev_probe,
.remove = xenbus_dev_remove,
+// .shutdown = xenbus_dev_shutdown,
.uevent = xenbus_uevent_backend,
},
.dev = {
const struct xenbus_device_id *id;
int err;
- DPRINTK("");
+ DPRINTK("%s", dev->nodename);
if (!drv->probe) {
err = -ENODEV;
struct xenbus_device *dev = to_xenbus_device(_dev);
struct xenbus_driver *drv = to_xenbus_driver(_dev->driver);
- DPRINTK("");
+ DPRINTK("%s", dev->nodename);
free_otherend_watch(dev);
free_otherend_details(dev);
return 0;
}
+static void xenbus_dev_shutdown(struct device *_dev)
+{
+ struct xenbus_device *dev = to_xenbus_device(_dev);
+ unsigned long timeout = 5*HZ;
+
+ DPRINTK("%s", dev->nodename);
+
+ get_device(&dev->dev);
+ if (dev->state != XenbusStateConnected) {
+ printk("%s: %s: %s != Connected, skipping\n", __FUNCTION__,
+ dev->nodename, xenbus_strstate(dev->state));
+ goto out;
+ }
+ xenbus_switch_state(dev, XenbusStateClosing);
+ timeout = wait_for_completion_timeout(&dev->down, timeout);
+ if (!timeout)
+ printk("%s: %s timeout closing device\n", __FUNCTION__, dev->nodename);
+ out:
+ put_device(&dev->dev);
+}
+
static int xenbus_register_driver_common(struct xenbus_driver *drv,
struct xen_bus_type *bus)
{
tmpstring += strlen(tmpstring) + 1;
strcpy(tmpstring, type);
xendev->devicetype = tmpstring;
+ init_completion(&xendev->down);
xendev->dev.parent = &bus->dev;
xendev->dev.bus = &bus->bus;
#include <linux/device.h>
#include <linux/notifier.h>
#include <linux/mutex.h>
+#include <linux/completion.h>
#include <xen/interface/xen.h>
#include <xen/interface/grant_table.h>
#include <xen/interface/io/xenbus.h>
struct xenbus_watch otherend_watch;
struct device dev;
enum xenbus_state state;
+ struct completion down;
};
static inline struct xenbus_device *to_xenbus_device(struct device *dev)
char *xenbus_strstate(enum xenbus_state state);
int xenbus_dev_is_online(struct xenbus_device *dev);
+int xenbus_frontend_closed(struct xenbus_device *dev);
#endif /* _XEN_XENBUS_H */